package client

import (
	"fmt"

	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/credentials/insecure"
	"starsine.cn/appTpl/cmn/config/aconf"
	. "starsine.cn/appTpl/cmn/defs"
	"starsine.cn/appTpl/cmn/logs"
	"starsine.cn/appTpl/cmn/utils"
	"starsine.cn/appTpl/svcregistry/grpc/svcregistryproto"
)

type GRpcClient struct {
	tls      bool
	addr     string
	certFile string

	conn    *grpc.ClientConn
	client  svcregistryproto.RegistryProtoClient
	appCtxt *AppContext
}

func CreateGRpcClient(appCtxt *AppContext, addr string) *GRpcClient {
	p := new(GRpcClient)

	p.addr = addr
	p.tls = aconf.GetBool("RPC.Tls", true, aconf.WithENV("rpc_tls"))
	p.certFile = utils.Path(aconf.GetString("RPC.CertFile", "conf/x509/cert.pem", aconf.WithENV("rpc_cert")))

	p.conn = nil
	p.client = nil
	p.appCtxt = appCtxt

	logs.Debugf("SC Registry CreateGRpcClient to svc: addr=%s, tls=%t, certFile=%s", p.addr, p.tls, p.certFile)

	return p
}

func (p *GRpcClient) Start() error {
	var opts []grpc.DialOption

	if p.tls {
		creds, err := credentials.NewClientTLSFromFile(p.certFile, "")
		if err != nil {
			logs.Warnf("GRpcClient to NewClientTLSFromFile fail, err: %s", err)
			return fmt.Errorf("GRpcClient to NewClientTLSFromFile fail, err: %s", err)
		}
		opts = append(opts, grpc.WithTransportCredentials(creds))
	} else {
		opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
	}

	conn, err := grpc.Dial(p.addr, opts...)
	if err != nil {
		logs.Errorf("GRpcClient to Dial fail, err: %s", err)
		return fmt.Errorf("GRpcClient to Dial fail, err: %s", err)
	}
	p.conn = conn

	p.client = svcregistryproto.NewRegistryProtoClient(conn)

	return nil
}

func (p *GRpcClient) End() {
	if p.conn != nil {
		p.conn.Close()
		p.conn = nil
	}
}
